#!/usr/bin/env python

class GrammarItem(object):
    def __init__(self,item):
        self.optional = False
        self.multiple = False
        key_split = item.split(':',1)
        if item[0] == '[':
            self.optional = True
            if item[1] == '<':
                self.kind = 'CLASS'
                self.type = key_split[0][2:]
                self.key = key_split[1][:-2]
            elif item[1] == "'":
                self.kind = 'TOKEN'
                self.token = item[2:-2]
            else:
                raise SyntaxError, "bad grammar file"
        elif item[0] == '<':
            self.kind = 'CLASS'
            self.type = key_split[0][1:]
            self.key = key_split[1][:-1]
        elif item[0] == "'":    
            self.kind = 'TOKEN'
            self.token = item[1:-1]
        else:
            raise SyntaxError, "bad grammar file"
        if self.kind == 'CLASS':
            if self.type[-1] == '*':
                self.type = self.type[:-1]
                self.multiple = True
                self.optional = True
            elif self.type[-1] == '+':
                self.type = self.type[:-1]
                self.multiple = True
        else:
            self.multiple = False
    def generate_python(self):
        if self.optional:
            func = "optional"
        else:
            func = "require"
        if self.multiple:
            func += '_multiple'
        if self.kind == 'TOKEN':
            return "        self." + func + "('" + self.token.replace('|',"','") + "')\n"
        else:
            return "        self." + self.key  + " = self." + func + "(" + self.type.replace('|',',') + ")\n"
        

def parse_grammar(grammar_file=None):
    with open(grammar_file or 'kal.grammar') as f:
        grammar = f.read()
    grammar_item = None
    grammar_parsed = {}
    for line in grammar.split('\n'):
        if grammar_item:
            grammar_parsed[grammar_item].extend([GrammarItem(item) for item in line.strip().split(' ') if item])
            grammar_item = None
        elif line !='':
            grammar_item = line[:-1].strip()
            grammar_parsed[grammar_item] = []
    python = ['class ' + grammar_item + '(KalASTNode):\n    def parse(self):\n' + ''.join([item.generate_python() for item in grammar_parsed[grammar_item]]) for grammar_item in grammar_parsed if grammar_item]
    with open('kal_parse.py','w') as f:
        f.write('#!/usr/bin/env python\n\n')
        f.write('#THIS FILE IS AUTOMATICALLY GENERATED\n\n')
        f.write('from KalAST import *\n\n')
        f.write('\n\n'.join(python))
if __name__ == '__main__':
    parse_grammar()